package irc

import (
	"net"
	"strconv"
	"sync"
	"sync/atomic"
	"time"
)

type Client struct {
	conn         net.Conn
	Id           uint64
	ReadTimeout  time.Duration
	WriteTimeout time.Duration
	once         *sync.Once
	Reqchain     chan *Message
	Rspchain     chan *Message
	Closechain   chan int
	Session      *Session
	Server       *Server
	DeviceToken  string
}

func NewsClient(server *Server, conn net.Conn) *Client {
	client := new(Client)
	client.Id = atomic.AddUint64(&server.clientids, 1)
	client.once = &sync.Once{}
	client.conn = conn
	client.ReadTimeout = time.Duration(server.Opts.TimeOut) * time.Second
	client.WriteTimeout = time.Duration(server.Opts.TimeOut) * time.Second
	client.Rspchain = make(chan *Message, 3)
	client.Reqchain = make(chan *Message, 3)
	client.Closechain = make(chan int, 1)
	client.Server = server
	return client
}

func (this *Client) Close() {
	this.once.Do(func() {

		if this.DeviceToken != "" {
			delete(this.Server.Clients, this.DeviceToken)
		}
		close(this.Rspchain)
		close(this.Reqchain)
		close(this.Closechain)
		this.conn.Close()
	})
}

func (this *Client) GetDeviceToken() string {
	if this.Session != nil && len(this.Session.DeviceId) > 0 && this.Session.AppId > 0 {
		return strconv.Itoa(this.Session.AppId) + "|" + this.Session.DeviceId
	}
	return ""
}

func (this *Client) IsConAuth() bool {

	if this.Session == nil {
		return false
	}
	if len(this.Session.DeviceId) == 0 {
		return false
	}

	if this.Session.AppId == 0 {
		return false
	}
	return true
}

func (this *Client) SendMessage(message *Message) {
	this.Rspchain <- message
}

